from rest_framework import serializers
from booktest.models import BookInfo, HeroInfo
import json


def check(value):
    if value %2 != 0:
        raise serializers.ValidationError('必须是偶数')
    return value


class HeroRelatedField(serializers.Serializer):
    id = serializers.IntegerField()
    hname = serializers.CharField()
    hgender = serializers.BooleanField()
    # hbook = serializers.CharField()


class BookSerializer(serializers.Serializer):
    # 关系属性：
    # heros = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
    # heros = serializers.StringRelatedField(read_only=True, many=True)
    heros = HeroRelatedField(read_only=True, many=True)

    id = serializers.IntegerField(read_only=True)
    btitle = serializers.CharField(
        min_length=3,
        max_length=10,
        error_messages={
            'min_length': '书名长度必须大于3',
            'max_length': '书名长度必须小于19'
        },
        label='书名',
        help_text='请输入书名'
    )
    bpub_date = serializers.DateField(write_only=True)
    bread = serializers.IntegerField(
        min_value=10,
        max_value=100,
        required=False,
        validators=[check]
    )
    bcomment = serializers.IntegerField(
        min_value=10,
        max_value=100,
        required=False
    )

    # 验证某一个属性：
    def validate_btitle(self, attr):
        # attr:请求字典中btitle对应的数据
        # 验证：书名中包含'django'
        if 'django' in attr:
            return attr
        else:
            return serializers.ValidationError('书名中必须包含django')

    # 验证多个属性：
    def validate(self, attrs):
        # attrs: 请求报文中的所有数据，字典

        # 验证：阅读量大于评论量
        bread = attrs.get('bread')
        bcomment = attrs.get('bcomment')
        if all([bread, bcomment]):
            if bread < bcomment:
                return serializers.ValidationError('阅读量应该大于评论量')

        return attrs

    def create(self, validated_data):
        # validated_data==>验证成功后的数据，类型为字典

        # book=BookInfo.objects.create(btitle=***, bpub_date=***)
        book = BookInfo.objects.create(**validated_data)
        return book

    def update(self, instance, validated_data):
        # instance ==> 需要被修改的对象
        # validated_data ==> 经过验证后的请求数据
        instance.btitle = validated_data.get('btitle')
        instance.bpub_date = validated_data.get('bpub_date')
        # ...
        instance.save()
        return instance


class HeroSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    hname = serializers.CharField()
    # hbook_id = serializers.IntegerField()

# 想要显示什么样的输出结果，就设置哪个（三选一）1、主键 2、字符串 3、自定义
    # 关系属性，必须指定read_only=True
    # 1、输出主键
    # hbook = serializers.PrimaryKeyRelatedField(read_only=True)
    # 2、输出字符串
    # hbook = serializers.StringRelatedField(read_only=True)
    # 3、自定义序列化器
    hbook = BookSerializer(read_only=True)

    def create(self, validated_data):
        hero = HeroInfo.objects.create(**validated_data)
        return hero

    def update(self, instance, validated_data):
        instance.hname = validated_data.get('hname')
        instance.hbook = validated_data.get('hbook')
        instance.hbook_id = validated_data.get('hbook_id')
        instance.save()
        return instance


class BookRelatedField(serializers.Serializer):
    id = serializers.IntegerField()
    btitle = serializers.CharField()
    bpub_data = serializers.DateField()


class HeroModelSerializer(serializers.ModelSerializer):
    books = BookRelatedField(read_only=True, many=True)

    class Meta:
        model = HeroInfo
        # fields = '__all__'
        fields = ('id', 'hname', 'hbook', 'books')
        read_only_field = ('id',)
        extra_kwargs = {
            'hname': {
                'min_length': 2,
                'max_length': 6,
                'error_messages': {
                    'min_length': '名字长度必须大于2',
                    'max_length': '名字长度必须小于6',
                }
            }
        }
    def validate_hname(self, attr):
        if 'drf' in attr:
            return attr
        else:
            raise serializers.ValidationError("名字中必须包含'drf'")



class BookModelSerializer(serializers.ModelSerializer):
    heros = HeroRelatedField(read_only=True, many=True)

    class Meta:
        model = BookInfo
        # fields = '__all__'
        fields = ('id', 'btitle', 'bpub_date', 'heros')
        read_only_fields = ('id',)
        extra_kwargs = {
            'btitle': {
                'min_length': 3,
                'max_length': 10,
                'error_messages': {
                    'min_length': '书名长度必须大于3',
                    'max_length': '书名长度必须小于19'
                }
            }
        }

    def validate_btitle(self, attr):
        if 'django' in attr:
            return attr
        else:
            raise serializers.ValidationError('书名中必须包含django')


class BookInfoSerializer(serializers.Serializer):
    """图书数据序列化器"""
    id = serializers.IntegerField(label='ID', read_only=True)
    btitle = serializers.CharField(label='名称', max_length=20)
    bpub_date = serializers.DateField(label='发布日前', required=False)
    bread = serializers.IntegerField(label='阅读量', required=False)
    bcomment = serializers.IntegerField(label='评论量', required=False)
    image = serializers.ImageField(label='图片', required=False)